// 数组响应式原理 重写数组的原型
const arrOriginPro = Array.prototype
const arrNewPro = Object.create(arrOriginPro)
const arrMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort']
arrMethods.forEach((methods) => {
    arrNewPro[methods] = function () {
        arrOriginPro[methods].apply(this, arguments)
        update()
    }
})

function isObj(obj) {
    return typeof obj === 'object'
}

function observe(obj) {
    if (!isObj(obj)) return;
    if (Array.isArray(obj)) {
        // 数组对象改写原型
        Object.setPrototypeOf(obj, arrNewPro)
    } else {
        const keys = Object.keys(obj)
        for (let index = 0; index < keys.length; index++) {
            const key = keys[index];
            const val = obj[key]
            // 取出对象每个key，对key进行数据拦截处理
            reactive(obj, key, val)
        }
    }
}

function reactive(obj, key, val) {
    // val可能是对想  故进行递归遍历拦截
    observe(val)
    Object.defineProperty(obj, key, {
        get() {
            console.log(`获取${key}==>值 ${val}`)
            return val
        },
        set(newVal) {
            if (newVal !== val) {
                // newVal可能也是对象，再次递归拦截
                observe(newVal)
                update()
                console.log(`设置${key}==>值 ${newVal}`)
                return val = newVal
            }
        }

    })

}

function update() {
    console.log('数据更新')
}

const data = {
    a: 1,
    b: 2,
    c: {
        name: "小明",
        age: 15
    },
    k: [1, 2, 3, 4]
}
observe(data)